/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.sentry.ohos.okhttp;


import java.io.IOException;

import io.sentry.Breadcrumb;
import io.sentry.HubAdapter;
import io.sentry.IHub;

import io.sentry.ISpan;
import io.sentry.SentryTraceHeader;
import io.sentry.SpanStatus;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * SentryOkHttpInterceptor
 *
 * @since 2021-05-25
 */
public class SentryOkHttpInterceptor implements Interceptor {
    private IHub hub = HubAdapter.getInstance();

    /**
     * intercept
     *
     * @param chain for intercept
     * @return Response
     * @throws IOException
     */
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        String url = request.url().toString();
        String method = request.method();
        ISpan span = null;
        if (hub.getSpan() != null) {
            span = hub.getSpan().startChild("http.client", method + " " + url);
        }

        Response response = null;
        Integer code = null;

        try {
            if (span != null) {
                SentryTraceHeader sentryTraceHeader = span.toSentryTrace();
                if (sentryTraceHeader != null) {
                    request = request.newBuilder().addHeader(sentryTraceHeader.getName(), sentryTraceHeader.getValue()).build();
                }
            }
            response = chain.proceed(request);
            code = response.code();
            if (span != null) {
                span.setStatus(SpanStatus.fromHttpStatusCode(code));
            }
            return response;
        } catch (IOException e) {
            if (span != null) {
                span.setThrowable(e);
                span.setStatus(SpanStatus.INTERNAL_ERROR);
            }
            throw e;
        } finally {
            if (span != null) {
                span.finish();
            }
            Breadcrumb breadcrumb = Breadcrumb.http(request.url().toString(), request.method(), code);
            RequestBody requestBody = request.body();
            if (requestBody != null) {
                long contentLength = requestBody.contentLength();
                if (contentLength != -1) {
                    breadcrumb.setData("requestBodySize", contentLength);
                }
            }

            if (response != null) {
                ResponseBody responseBody = response.body();
                long contentLength = responseBody.contentLength();
                if (contentLength != -1) {
                    breadcrumb.setData("responseBodySize", contentLength);
                }
            }
            hub.addBreadcrumb(breadcrumb);
        }
    }
}
